本篇聚焦「讀者如何將 C 擴充的 Ruby 專案做成跨平台預編譯」,以 GitHub Actions 的 matrix native compile 為主軸,並示範 artifacts 與目錄 tree 的管理、跨平台打包與回退策略。內容讀者取向,可直接複製 YAML 進行調整。
——
——
workflow_call 呼叫。這種切分能讓讀者把「平台差異」集中在重用工作流,產品側只需要專注版本與簽名/發佈細節。
——
以下提供單檔精簡版,讀者可依專案拆為多個可重用工作流。示例採用 Ruby bundler 與 rake-compiler 常見流程;若專案直接以 extconf.rb 編譯核心原始碼,也同樣適用。
name: build-and-release
on:
  push:
    tags:
      - "v*.*.*"
jobs:
  build-matrix:
    name: build (${{ matrix.os }} / ${{ matrix.ruby }} / ${{ matrix.libc || 'mac/win' }})
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: macos-13
            ruby: "3.2"
            arch: x86_64
          - os: macos-14
            ruby: "3.2"
            arch: arm64
          - os: ubuntu-22.04
            ruby: "3.2"
            libc: glibc
          - os: ubuntu-22.04
            ruby: "3.2"
            libc: musl
          - os: windows-2022
            ruby: "3.2"
    steps:
      - uses: actions/checkout@v4
      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby }}
          bundler-cache: true
      - name: Install deps (Linux)
        if: startsWith(matrix.os, 'ubuntu')
        run: |
          sudo apt-get update
          sudo apt-get install -y build-essential pkg-config
      - name: Build gem (native)
        run: |
          bundle install --jobs 4 --retry 3
          bundle exec rake compile
          bundle exec rake build
      - name: Archive artifact
        uses: actions/upload-artifact@v4
        with:
          name: pkg-${{ matrix.os }}-${{ matrix.arch || matrix.libc || 'win' }}
          path: |
            pkg/*.gem
            ext/mongory_ext/*.so
            ext/mongory_ext/*.bundle
            ext/mongory_ext/*.dll
  release:
    needs: build-matrix
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4
      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts
      - name: Inspect tree
        run: |
          tree -a artifacts || ls -R artifacts
      - name: Publish gems
        env:
          RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
        run: |
          # 1) 建議先發佈 source gem(可回退且通用)
          gem push pkg/*.gem || true
          # 2) 再針對各平台的 gem(若有)逐一發佈
          find artifacts -name '*.gem' -print -exec gem push {} \; || true
說明:
windows-2022 runner。——
tree 檢視,能快速對齊目錄與檔名。——
.dll 與 Ruby 版本對應,建議在 CI 中以矩陣覆蓋常見 Ruby 版本。.so/.bundle/.dll 可被 require。——
——
——
結語:CI/CD 與預編譯的關鍵,是把平台差異集中治理、把產出物管好、把回退路徑留好。沿用本文 YAML 與策略,讀者可在一兩個迭代內,把任何含 C 擴充的 Ruby 專案升級為「可預編譯、可回退、可維運」的產品級流程。